package com.xin.wx;

import com.google.auto.service.AutoService;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.TypeSpec;
import com.xin.annotation.wx.WxPay;
import com.xin.annotation.wx.WxSocial;

import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;

/**
 * 根据注解生成
 */
@AutoService(Processor.class)
public class WxProcessor extends AbstractProcessor {

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        HashSet<String> supportTypes = new LinkedHashSet<>();
        supportTypes.add(WxSocial.class.getCanonicalName());
        supportTypes.add(WxPay.class.getCanonicalName());
        return supportTypes;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        Set<? extends Element> elementsWxSocial = roundEnvironment.getElementsAnnotatedWith(WxSocial.class);
        if (elementsWxSocial.size() > 0) {
            Element element = elementsWxSocial.iterator().next();
            doWxSocial(element);
        }
        Set<? extends Element> elementsWxPay = roundEnvironment.getElementsAnnotatedWith(WxPay.class);
        if (elementsWxPay.size() > 0) {
            Element element = elementsWxPay.iterator().next();
            doWxPay(element);
        }
        return true;
    }

    private void doWxPay(Element element) {
        WxPayOptUtils utils = new WxPayOptUtils();
        String packageName = element.getAnnotation(WxPay.class).value();
        TypeSpec typeSpec = TypeSpec.classBuilder("WXPayEntryActivity")
                .addModifiers(Modifier.PUBLIC)
                .addField(utils.getIWXAPI())
                .addMethod(utils.getOnCreate())
                .addMethod(utils.getOnReq())
                .addMethod(utils.getOnResp())
                .addMethod(utils.getOnNewIntent())
                .addMethod(utils.getLog())
                .addMethod(utils.getShowToast())
                .superclass(ClassName.get("android.app","Activity"))
                .addSuperinterface(ClassName.get("com.tencent.mm.opensdk.openapi","IWXAPIEventHandler"))
                .build();

        JavaFile.Builder builder = JavaFile.builder(packageName+".wxapi", typeSpec);
        JavaFile javaFile = builder.build();

        try {
            Filer mFiler = processingEnv.getFiler();
            javaFile.writeTo(mFiler);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param element
     */
    private void doWxSocial(Element element) {
        WxSocialOptUtils utils = new WxSocialOptUtils();
        String packageName = element.getAnnotation(WxSocial.class).value();
        TypeSpec typeSpec = TypeSpec.classBuilder("WXEntryActivity")
                .addModifiers(Modifier.PUBLIC)
                .addField(utils.getIWXAPI())
                .addMethod(utils.getOnCreate())
                .addMethod(utils.getOnReq())
                .addMethod(utils.getOnResp())
                .addMethod(utils.getOnSuccess())
                .addMethod(utils.getOnCancel())
                .addMethod(utils.getOnFail())
                .addMethod(utils.getLog())
                .addMethod(utils.getShowToast())
                .superclass(ClassName.get("android.app","Activity"))
                .addSuperinterface(ClassName.get("com.tencent.mm.opensdk.openapi","IWXAPIEventHandler"))
                .build();

        JavaFile.Builder builder = JavaFile.builder(packageName+".wxapi", typeSpec);
        JavaFile javaFile = builder.build();

        try {
            Filer mFiler = processingEnv.getFiler();
            javaFile.writeTo(mFiler);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
